//
//  LoanProcessViewController.swift
//  EasyDana
//
//  Created by mac on 2024/10/11.
//

import UIKit
import RxSwift
import RxCocoa
class LoanProcessViewController: UIViewController {

    @IBOutlet weak var stackView: UIStackView!
    
    private let agree = BehaviorRelay(value: true)
    
    @IBOutlet weak var agreeButton: UIButton!
    
    @IBOutlet weak var naviBar: NavigationBar!
    
    struct LoanProcessModel: Codable {
        struct DisplayModel: Codable {
            
            struct DisplayDetailModel: Codable {
                struct DetailModel: Codable {
                    let convoys: String
                    let robe: String
                }
                let pathways: DetailModel
                let cheaply: DetailModel
            }
            let elegant: String//产品名称
            let expressed: String//金额
            let arts: String//借款金额文案
            let verses: DisplayDetailModel
            let evenings: String
            let perdition: String //订单号
            let stains: String//借款期限
            let blisters: Int//期限类型
            init(from decoder: any Decoder) throws {
                let container = try decoder.container(keyedBy: CodingKeys.self)
                self.elegant = try container.decode(String.self, forKey: .elegant)
                do {
                    self.expressed = try container.decode(String.self, forKey: .expressed)
                } catch {
                    let e = try container.decode(Float.self, forKey: .expressed)
                    self.expressed = "\(e)"
                }
                self.arts = try container.decode(String.self, forKey: .arts)
                self.evenings = try container.decode(String.self, forKey: .evenings)
                self.perdition = try container.decode(String.self, forKey: .perdition)
                self.stains = try container.decode(String.self, forKey: .stains)
                self.blisters = try container.decode(Int.self, forKey: .blisters)
                self.verses = try container.decode(DisplayDetailModel.self, forKey: .verses)
            }
            
        }
        struct AuthenticationModel: Codable {
            let convoys: String
            let entail: String
            let cordially: Int
            let drank: String
            let alive: Int
            let comply: String
            let bier: String
            let strew: Int
            let unavailing: Int
            let remembrance: String
            let tomb: String
        }
        struct VerseModel: Codable {
            let bier: String
            let drank: String
            let cordially: Int
            let convoys: String
            
            init(from decoder: any Decoder) throws {
                let container: KeyedDecodingContainer<LoanProcessViewController.LoanProcessModel.VerseModel.CodingKeys> = try decoder.container(keyedBy: LoanProcessViewController.LoanProcessModel.VerseModel.CodingKeys.self)
                self.bier = try container.decode(String.self, forKey: LoanProcessViewController.LoanProcessModel.VerseModel.CodingKeys.bier)
                self.drank = try container.decode(String.self, forKey: LoanProcessViewController.LoanProcessModel.VerseModel.CodingKeys.drank)
                self.cordially = try container.decode(Int.self, forKey: LoanProcessViewController.LoanProcessModel.VerseModel.CodingKeys.cordially)
                self.convoys = try container.decode(String.self, forKey: LoanProcessViewController.LoanProcessModel.VerseModel.CodingKeys.convoys)
            }
        }
        struct Clements: Codable {
            let convoys: String
            let jno: String
        }
        let display: DisplayModel
        let forfeiture: [AuthenticationModel]
        let clements: Clements
        let verse: VerseModel?
        init(from decoder: any Decoder) throws {
            let container = try decoder.container(keyedBy: CodingKeys.self)
            self.display = try container.decode(LoanProcessModel.DisplayModel.self, forKey: .display)
            self.forfeiture = try container.decode([LoanProcessModel.AuthenticationModel].self, forKey: .forfeiture)
            self.clements = try container.decode(LoanProcessModel.Clements.self, forKey: .clements)
            do {
                self.verse = try container.decodeIfPresent(LoanProcessModel.VerseModel.self, forKey: .verse)
            } catch {
                self.verse = nil
            }
        }
    }
    
    var id: String = ""
    
    private let bag = DisposeBag()
    
    private let data = BehaviorRelay<LoanProcessModel?>.init(value: nil)
    
    @IBOutlet weak var titleLabel: UILabel!
    
    @IBOutlet weak var amountLabel: UILabel!
    
    @IBOutlet weak var dateLabel: UILabel!
    
    @IBOutlet weak var dateDescLabel: UILabel!
    
    @IBOutlet weak var rateLabel: UILabel!
    
    @IBOutlet weak var rateDescLabel: UILabel!
    
    @IBOutlet weak var scrollView: UIScrollView!
    
    @IBOutlet weak var loadProgressView: LoanProgressView!
    
    @IBOutlet weak var loanButton: UIButton!
    
    @IBOutlet weak var agreementView: UIView!
    
    @IBOutlet weak var agreementTitleButton: UIButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.scrollView.contentInsetAdjustmentBehavior = .never
        self.configView()
        // Do any additional setup after loading the view.
    }
    
    private func configView() {
        self.naviBar.backClicked
            .subscribe(onNext: { [weak self] _ in
                self?.navigationController?.popViewController(animated: true)
            })
            .disposed(by: self.bag)
        self.naviBar.title = "Detail produk".locale
        self.agreeButton.setImage(UIImage(named: "login_agree_uncheck"), for: .normal)
        self.agreeButton.setImage(UIImage(named: "login_agree_check"), for: .selected)
        self.agreeButton.rx.tap
            .subscribe(onNext: { [weak self] event in
                self?.agree.accept(!self!.agree.value)
            })
            .disposed(by: self.bag)
        self.agree.bind(to: self.agreeButton.rx.isSelected).disposed(by: self.bag)
        self.data.map { model in
            return model?.display.elegant
        }
        .subscribe { [weak self] name in
            self?.naviBar.title = name
        }
        .disposed(by: self.bag)
        self.data
            .map { model in
                return model?.display.arts
            }
            .bind(to: self.titleLabel.rx.text)
            .disposed(by: self.bag)
        self.data
            .map { model in
                return model?.display.expressed
            }
            .bind(to: self.amountLabel.rx.text)
            .disposed(by: self.bag)
        self.data.map { model in
            return model?.display.verses.pathways.robe
        }
        .bind(to: self.dateLabel.rx.text)
        .disposed(by: self.bag)
        self.data.map { model in
            return model?.display.verses.pathways.convoys
        }
        .bind(to: self.dateDescLabel.rx.text)
        .disposed(by: self.bag)
        self.data.map { model in
            return model?.display.verses.cheaply.robe
        }
        .bind(to: self.rateLabel.rx.text)
        .disposed(by: self.bag)
        self.data.map { model in
            return model?.display.verses.cheaply.convoys
        }
        .bind(to: self.rateDescLabel.rx.text)
        .disposed(by: self.bag)
        self.data.filter({$0 != nil}).map { model in
            return model!.clements
        }
        .subscribe(onNext: { [weak self] model in
            let jno = model.jno
            let convoys = model.convoys
            self?.agreementView.isHidden = !jno.hasPrefix("http")
            self?.agreementTitleButton.setTitle(convoys, for: .normal)
        })
        .disposed(by: self.bag)
        self.data.map { model in
            let list = model?.forfeiture ?? []
            return list.map { m in
                let view = Bundle.main.loadNibNamed("LoanStepView", owner: nil)?.first as! LoanStepView
                view.onClickModel = { [weak self] mm in
                    let target = mm.bier
                    if mm.alive == 1 {
                        switch target {
                        case "contract":
                            //公共
                            let idViewController = UserIDCardViewController()
                            idViewController.product_id = self?.id ?? ""
                            idViewController.naviTitle = mm.convoys
                            self?.navigationController?.pushViewController(idViewController, animated: true)
                            break
                        case "emblem":
                            //个人信息页
                            let personalInfoVC = AuthenticateViewController()
                            personalInfoVC.riskType = 4
                            personalInfoVC.step = 2
                            personalInfoVC.totalStep = list.count
                            personalInfoVC.product_id = self?.id ?? ""
                            personalInfoVC.naviTitle = mm.convoys
                            personalInfoVC.getApi = Api.getUserBasicInfo
                            personalInfoVC.saveApi = Api.saveUserBasicInfo
                            self?.navigationController?.pushViewController(personalInfoVC, animated: true)
                            break
                        case "most":
                            //job
                            let personalInfoVC = AuthenticateViewController()
                            personalInfoVC.riskType = 5
                            personalInfoVC.step = 3
                            personalInfoVC.totalStep = list.count
                            personalInfoVC.product_id = self?.id ?? ""
                            personalInfoVC.naviTitle = mm.convoys
                            personalInfoVC.getApi = Api.getJobInfo
                            personalInfoVC.saveApi = Api.saveJobInfo
                            self?.navigationController?.pushViewController(personalInfoVC, animated: true)
                            break
                        case "best":
                            //ext
                            let personalInfoVC = ContactsViewController()
                            personalInfoVC.step = 4
                            personalInfoVC.totalStep = list.count
                            personalInfoVC.product_id = self?.id ?? ""
                            personalInfoVC.naviTitle = mm.convoys
                            self?.navigationController?.pushViewController(personalInfoVC, animated: true)
                            break
                        case "love":
                            //银行
                            let personalInfoVC = AuthenticateViewController()
                            personalInfoVC.riskType = 7
                            personalInfoVC.step = list.count == 5 ? 5 : 4
                            personalInfoVC.totalStep = list.count
                            personalInfoVC.product_id = self?.id ?? ""
                            personalInfoVC.naviTitle = mm.convoys
                            personalInfoVC.getApi = Api.getCardInfo
                            personalInfoVC.saveApi = Api.saveCardInfo
                            self?.navigationController?.pushViewController(personalInfoVC, animated: true)
                            break
                        default:
                            break
                        }
                    } else {
                        self?.loanAction(UIButton())
                    }
                }
                view.model = m
                return view
            }
        }
        .observe(on: MainScheduler.instance)
        .subscribe(onNext: { [weak self] views in
            let oldViews = self?.stackView.arrangedSubviews
            oldViews?.forEach({ view in
                view.removeFromSuperview()
            })
            views.forEach({self?.stackView.addArrangedSubview($0)})
        })
        .disposed(by: self.bag)
        self.data.map { model in
            return model?.forfeiture.filter({$0.alive == 1}).count ?? 0
        }
        .bind(to: self.loadProgressView.step)
        .disposed(by: self.bag)
        self.data.map { model in
            return model?.display.evenings
        }
        .bind(to: self.loanButton.rx.title(for: .normal))
        .disposed(by: self.bag)
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.getData()
    }
    
    @IBAction func loanAction(_ sender: UIButton) {
        let mm = self.data.value?.verse
        let target = mm?.bier ?? ""
        switch target {
        case "contract":
            //公共
            let idViewController = UserIDCardViewController()
            idViewController.product_id = self.id
            idViewController.naviTitle = mm?.convoys ?? ""
            self.navigationController?.pushViewController(idViewController, animated: true)
            break
        case "emblem":
            //个人信息页
            let personalInfoVC = AuthenticateViewController()
            personalInfoVC.riskType = 4
            personalInfoVC.step = 2
            personalInfoVC.totalStep = self.data.value?.forfeiture.count ?? 0
            personalInfoVC.product_id = self.id
            personalInfoVC.naviTitle = mm?.convoys ?? ""
            personalInfoVC.getApi = Api.getUserBasicInfo
            personalInfoVC.saveApi = Api.saveUserBasicInfo
            self.navigationController?.pushViewController(personalInfoVC, animated: true)
            break
        case "most":
            //job
            let personalInfoVC = AuthenticateViewController()
            personalInfoVC.riskType = 5
            personalInfoVC.step = 3
            personalInfoVC.totalStep = self.data.value?.forfeiture.count ?? 0
            personalInfoVC.product_id = self.id
            personalInfoVC.naviTitle = mm?.convoys ?? ""
            personalInfoVC.getApi = Api.getJobInfo
            personalInfoVC.saveApi = Api.saveJobInfo
            self.navigationController?.pushViewController(personalInfoVC, animated: true)
            break
        case "best":
            //ext
            let personalInfoVC = ContactsViewController()
            personalInfoVC.step = 4
            personalInfoVC.totalStep = self.data.value?.forfeiture.count ?? 0
            personalInfoVC.product_id = self.id
            personalInfoVC.naviTitle = mm?.convoys ?? ""
            self.navigationController?.pushViewController(personalInfoVC, animated: true)
            break
        case "love":
            //银行
            let personalInfoVC = AuthenticateViewController()
            personalInfoVC.riskType = 7
            personalInfoVC.step = (self.data.value?.forfeiture.count ?? 0) == 5 ? 5 : 4
            personalInfoVC.totalStep = (self.data.value?.forfeiture.count ?? 0)
            personalInfoVC.product_id = self.id
            personalInfoVC.naviTitle = mm?.convoys ?? ""
            personalInfoVC.getApi = Api.getCardInfo
            personalInfoVC.saveApi = Api.saveCardInfo
            self.navigationController?.pushViewController(personalInfoVC, animated: true)
            break
        default:
            if (self.agree.value == false) {
                self.show(toast: "please read and agree to the <Loan Agreement>".locale)
                return
            }
            Task {
                struct CreateOrderModel: Codable {
                    let drank: String
                }
                do {
                    self.showLoading(text: nil)
                    let res = try await HTTPManager.default.post(path: Api.createOrder, param: [
                        "perdition": self.data.value!.display.perdition, "expressed": self.data.value!.display.expressed, "blisters": self.data.value!.display.blisters, "stains": self.data.value!.display.stains], dataType: CreateOrderModel.self)
                    if res.code == 0 {
                        let drank = res.data?.drank ?? ""
                        UploadStasticManager.default.uploadRiskPoint(type: 8, beginTime: Date(), orderNo: self.data.value?.display.perdition ?? "")
                        self.hideLoading()
                        if let url = URL(string: drank) {
                            let vc = self.jump(url: url, notJump: true)
                            self.navigationController?.replace(viewController: vc, animated: true)
                        } else {
                            self.navigationController?.popViewController(animated: true)
                        }
                    } else {
                        self.hideLoading()
                        self.show(toast: res.state)
                    }
                } catch {
                    self.hideLoading()
                    self.show(toast: error.localizedDescription)
                }
            }
            break
        }
    }
    
    @IBAction func showAgreementAction(_ sender: UIButton) {
        let jno = self.data.value?.clements.jno ?? ""
        let webVC = WebViewController()
        webVC.hidesBottomBarWhenPushed = true
        webVC.url = jno
        self.navigationController?.pushViewController(webVC, animated: true)
    }
    
    private func getData() {
        Task {
            do {
                self.showLoading(text: nil)
                let res = try await HTTPManager.default.post(path: Api.detail, param: ["guns": self.id], dataType: LoanProcessModel.self)
                print(res.data)
                self.data.accept(res.data)
                self.hideLoading()
            } catch {
                print(error)
                self.hideLoading()
                self.show(toast: error.localizedDescription)
            }
        }
    }
    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    */

}
